package tech.xs.sys.controller;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import tech.xs.common.framework.domain.annotations.AuthApi;
import tech.xs.common.framework.domain.entity.BaseEntity;
import tech.xs.common.framework.domain.enums.DataSourceTypeEnum;
import tech.xs.common.framework.domain.model.ApiResult;
import tech.xs.common.framework.domain.model.PageResult;
import tech.xs.common.sys.domain.constant.PermissionConstant;
import tech.xs.sys.domain.bo.dict.ManualEditChildDictBo;
import tech.xs.sys.domain.bo.dict.PageChildDictBo;
import tech.xs.sys.domain.entity.SysChildDict;
import tech.xs.sys.domain.entity.SysChildDictData;
import tech.xs.sys.domain.entity.SysDict;
import tech.xs.sys.service.SysChildDictDataService;
import tech.xs.sys.service.SysChildDictService;
import tech.xs.sys.service.SysDictService;

import javax.annotation.Resource;

/**
 * 子字典管理
 *
 * @author 沈家文
 * @since 2023/5/17$ 17:56$
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/dict/child")
public class SysChildDictController {

    @Resource
    private SysDictService sysDictService;
    @Resource
    private SysChildDictService sysChildDictService;
    @Resource
    private SysChildDictDataService sysChildDictDataService;

    /**
     * 根据id查询子字典信息
     *
     * @param id id
     * @return 响应数据
     * @author 沈家文
     * @since 2023/5/26 16:16
     */
    @GetMapping("/get/id")
    @AuthApi(permissions = PermissionConstant.DICT_MGR)
    public ApiResult<SysChildDict> getById(@RequestParam Long id) {
        return ApiResult.success(sysChildDictService.getById(id));
    }

    @GetMapping("/list/page")
    @AuthApi(permissions = PermissionConstant.DICT_MGR)
    public PageResult<SysChildDict> page(@ModelAttribute PageChildDictBo bo) {
        return PageResult.success(sysChildDictService.selectJoinListPage(bo.page(), SysChildDict.class, bo.query()));
    }

    @PostMapping("/saveOrUpdate/manual")
    @AuthApi(permissions = PermissionConstant.DICT_MGR)
    public ApiResult<SysChildDict> manualEdit(@Validated @RequestBody ManualEditChildDictBo bo) {
        bo.checkParameter();
        SysDict dict = sysDictService.getOne(Wrappers.<SysDict>lambdaQuery().eq(SysDict::getCode, bo.getDictCode()));
        if (dict == null) {
            return ApiResult.error("字典不存在 dictCode:" + bo.getDictCode());
        }

        long existCount = sysChildDictService.count(Wrappers.<SysChildDict>lambdaQuery()
                .eq(SysChildDict::getCode, bo.getCode())
                .eq(SysChildDict::getDictId, dict.getId())
                .ne(bo.getId() != null, BaseEntity::getId, bo.getId()));
        if (existCount > 0) {
            return ApiResult.error("字典绑定子字典编码已经存在");
        }

        SysChildDict saveData = new SysChildDict();
        BeanUtil.copyProperties(bo, saveData);
        if (bo.getId() != null) {
            SysChildDict dbData = sysChildDictService.getOne(Wrappers.<SysChildDict>lambdaQuery().eq(BaseEntity::getId, bo.getId()));
            if (dbData == null) {
                return ApiResult.error("根据id在系统中未查询到数据");
            }
            if (DataSourceTypeEnum.SystemGeneration.equals(dbData.getSource())) {
                return ApiResult.error("系统生成子字典禁止修改");
            }
            if (!dbData.getDictId().equals(dict.getId())) {
                return ApiResult.error("不允许修改子字典绑定的字典");
            }
            if (!bo.getCode().equals(dbData.getCode())) {
                sysDictService.deleteChildDictCache(bo.getDictCode(), dbData.getCode());
            }
        }
        saveData.setSource(DataSourceTypeEnum.Manual);
        saveData.setDictId(dict.getId());
        log.info("手动更新或保存子字典:" + saveData);
        sysChildDictService.saveOrUpdate(saveData);
        sysDictService.reloadChildDictCache(bo.getDictCode(), bo.getCode());
        return ApiResult.success(saveData);
    }

    /**
     * 根据id删除子字典
     *
     * @param id id
     * @return 响应数据
     * @author 沈家文
     * @since 2023/5/24 16:11
     */
    @DeleteMapping("/delete/id")
    @AuthApi(permissions = PermissionConstant.DICT_MGR)
    public ApiResult<String> deleteByCode(@RequestParam Long id) {
        if (id == null) {
            return ApiResult.error("id不能为空");
        }
        SysChildDict deleteData = sysChildDictService.getById(id);
        if (deleteData == null) {
            return ApiResult.error("子字典数据不存在或已删除 id" + id);
        }
        SysDict dict = sysDictService.getById(deleteData.getDictId());
        log.info("删除子字典:" + deleteData);
        sysChildDictService.removeById(id);
        sysChildDictDataService.remove(Wrappers.<SysChildDictData>lambdaQuery().eq(SysChildDictData::getChildDictId, id));
        sysDictService.deleteChildDictCache(dict.getCode(), deleteData.getCode());
        return ApiResult.success();
    }

}
